package com.sys.basics.config.socketio;

import com.corundumstudio.socketio.SocketConfig;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.store.RedissonStoreFactory;
import com.corundumstudio.socketio.store.pubsub.DispatchMessage;
import com.corundumstudio.socketio.store.pubsub.PubSubListener;
import com.corundumstudio.socketio.store.pubsub.PubSubStore;
import com.corundumstudio.socketio.store.pubsub.PubSubType;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.codec.JsonJacksonCodec;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class NettySocketIoConfig {
    @Value("${socketio.host}")
    private String host;

    @Value("${socketio.port}")
    private Integer port;

    @Value("${socketio.bossCount}")
    private int bossCount;

    @Value("${socketio.workCount}")
    private int workCount;

    @Value("${socketio.allowCustomRequests}")
    private boolean allowCustomRequests;

    @Value("${socketio.upgradeTimeout}")
    private int upgradeTimeout;

    @Value("${socketio.pingTimeout}")
    private int pingTimeout;

    @Value("${socketio.pingInterval}")
    private int pingInterval;

    @Value("${socketio.redissonAddress}")
    private String redissonAddress;

    @Value("${socketio.redissonPwd}")
    private String redissonPwd;

    @Bean
    public RedissonClient redissonClient(){
        Config redissonConfig = new Config();
        redissonConfig.useSingleServer().setAddress(redissonAddress).setPassword(redissonPwd);
        Codec codec = new JsonJacksonCodec();
        redissonConfig.setCodec(codec);
        return Redisson.create(redissonConfig);
    }

    @Bean
    public RedissonStoreFactory socketIoStoreFactory(RedissonClient redissonClient){
        return new RedissonStoreFactory(redissonClient);
    }

    @Bean
    public PubSubStore socketIoPubSubStore(RedissonStoreFactory socketIoStoreFactory){
        PubSubStore pubSubStore = socketIoStoreFactory.pubSubStore();
        pubSubStore.subscribe(PubSubType.DISPATCH, new PubSubListener<DispatchMessage>() {
            @Override
            public void onMessage(DispatchMessage msg) {

                System.out.println(msg);
            }
        }, DispatchMessage.class);
        return pubSubStore;
    }

    @Bean
    public SocketIOServer nettySocketIOServer(RedissonStoreFactory socketIoStoreFactory) {
        SocketConfig socketConfig = new SocketConfig();
        socketConfig.setReuseAddress(true);
        socketConfig.setTcpNoDelay(true);
        socketConfig.setSoLinger(0);

        com.corundumstudio.socketio.Configuration config = new com.corundumstudio.socketio.Configuration();
        config.setSocketConfig(socketConfig);
        // jenkins docker发布时不需要配置host
        if (!host.equals("none")) {
            config.setHostname(host);
        }
        config.setPort(port);
        config.setOrigin(null);
        config.setBossThreads(bossCount);
        config.setWorkerThreads(workCount);
        config.setAllowCustomRequests(allowCustomRequests);
        config.setUpgradeTimeout(upgradeTimeout);
        config.setPingTimeout(pingTimeout);
        config.setPingInterval(pingInterval);

        config.setStoreFactory(socketIoStoreFactory);

        return new SocketIOServer(config);
    }

}
